﻿@page "/playground"
@inject ICurrentContext CurrentContext
@inject IOptionsSnapshot<PasswordlessManagementOptions> Options
@inject IAntiforgery Antiforgery
@using Microsoft.AspNetCore.Antiforgery
@using Microsoft.Extensions.Options
@using Passwordless.AdminConsole.Middleware
@using Passwordless.AdminConsole.Services.PasswordlessManagement
@model ClientModel

@{
    ViewData["Title"] = "Playground";
    var requestToken = Antiforgery.GetAndStoreTokens(Model.HttpContext).RequestToken;
}

<div id="xapp" class="flex flex-col gap-10">
    <div class="flex flex-1 flex-col justify-center lg:flex-none bg-gray-200 rounded-md p-6 max-w-fit">
        <div class="w-full max-w-sm lg:w-96">
            <div>
                <h2 class="text-2xl font-bold tracking-tight text-gray-900">Sign in to your account</h2>
                <p class="mt-2 text-sm text-gray-600">
                    Don't have an account?
                    <a asp-page="newAccount" class="font-medium text-primary-500 hover:text-blue-500">Create account</a>
                </p>
            </div>

            <div class="mt-8">
                <div class="mt-4">
                    <form v-on:submit.prevent="loginSubmit" href="#" name="signin" method="post">
                        <div class="sm:hidden">
                            <label for="tabs" class="sr-only">Select a tab</label>
                            <select id="tabs" name="tabs" class="block w-full rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500" v-on:change.prevent="setTabSelect">
                                <option v-for="tab in tabs" :key="tab.name" :selected="tab.current">{{ tab.name }}</option>
                            </select>
                        </div>
                        <div class="hidden sm:block">
                            <div class="border-b border-gray-200 -mb-px flex" aria-label="Tabs">
                                <button v-for="tab in tabs" :key="tab.name" v-on:click.prevent="setTab(tab)" :class="[tab.current ? 'border-indigo-500 text-indigo-600' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700', 'flex-grow border-b-2 px-1 py-4 text-center text-sm font-medium']" :aria-current="tab.current ? 'page' : undefined">{{ tab.name }}</button>
                            </div>
                        </div>
                        <fieldset id="registerCredentialFields" class="space-y-6 mt-4">
                            <div>
                                <label for="alias" class="block text-sm font-medium leading-6 text-gray-900">Email address / username</label>
                                <div class="mt-2">
                                    <input id="alias" name="alias" type="text" autocomplete="webauthn" required class="text-input">
                                </div>
                            </div>

                            <div v-if="isStepUp" class="flex flex-col">
                                <p class="inline-flex items-center" v-on:click="setShowOptions">
                                    <svg class="w-6 h-6 fill-current" :class="{ 'rotate-90': showOptions }" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
                                    </svg>Sign in options:
                                </p>
                                <div class="ml-4" v-if="showOptions">
                                    @foreach (var purpose in Model.Purposes)
                                    {
                                        <label class="block"><input class="mr-2" name="selectedPurpose" v-model="selectedPurpose" value="@purpose" type="radio"/>@purpose</label>
                                    }
                                </div>
                            </div>

                            <div>
                                <button type="submit" class="flex w-full justify-center rounded-md bg-primary-500 py-2 px-3 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500">{{submitLabel}}</button>
                            </div>

                            <div id="webauthn-unsupported-alert" class="hidden">
                                <danger-alert-box message="WebAuthn is not supported in this browser."></danger-alert-box>
                            </div>
                        </fieldset>
                    </form>
                </div>
            </div>
        </div>
    </div>
    <div v-cloak>
        <div v-if="signins.length > 0" v-for="item in signins.slice().reverse()" class="overflow-hidden bg-white shadow sm:rounded-lg mb-4">
            <div class="border-t border-gray-200 px-4 py-5 sm:px-6">
                <dl class="grid grid-cols-1 gap-x-4 gap-y-8 sm:grid-cols-2">
                    <div v-for="(value, name) in item" class="sm:col-span-1">
                        <dt class="text-sm font-medium text-gray-500 ">{{ name }}</dt>
                        <dd class="mt-1 text-sm text-gray-900 font-mono" style="overflow-wrap: break-word;">{{ value || '-' }}</dd>
                    </div>
                </dl>
            </div>
        </div>
        <div v-if="signins.length == 0" class="relative block w-full rounded-lg border-2 border-dashed border-gray-400 p-12 text-center max-w-lg">
            <svg class="mx-auto h-12 w-12 text-gray-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
            </svg>

            <span class="mt-2 block text-sm font-semibold text-gray-900">Successful Logins</span>
        </div>
    </div>
</div>


<style>
  .signin-item {
    padding: 10px;
    display: flex;
    background-color: #eee;
    border-radius: 5px;
    gap: 5px;
    flex-wrap: wrap;
  }

  .item-pair {
    padding: 5px;
    background: #c2d5dd;
    border-radius: 3px;
  }
</style>

@section Scripts {
    <script type="module">
        import { createApp, ref, computed } from 'vue';
        createApp({
            setup() {
                const signins = ref([]);
                const selectedPurpose = ref("sign-in");
                const showOptions = ref(false);

                const setShowOptions = (_) => {
                    showOptions.value = !showOptions.value;
                }

                const tabs = ref([
                    { name: 'Sign In' , current: true },
                    { name: 'Step Up' , current: false }
                ]);

                const setTab = (tab) => {
                    clearCurrent();
                    tabs.value.find(x => x.name === tab.name).current = true;
                };

                const setTabSelect = (event) => {
                    clearCurrent();

                    tabs.value.find(x => x.name === event.target.value).current = true;
                };

                function clearCurrent()
                {
                    tabs.value.forEach(x => {
                        x.current = false;
                    });
                }

                const submitLabel = computed(() => {
                    return tabs.value.find(x => x.current).name;
                });

                const isStepUp = computed(() => {
                    return tabs.value.find(x => x.current).name === 'Step Up';
                });

                const p = new Passwordless.Client({
                    apiUrl: "@Options.Value.ApiUrl",
                    apiKey: "@CurrentContext.ApiKey"
                });

                const autoFill = async (retries) => {
                    if (retries <= 0) return;

                    const {token, error} = await p.signinWithAutofill();
                    console.log("Signin with autofill returned with", token, error);
                    if (token) {
                        await signin(token)
                        await autoFill(retries - 1);
                    } else {
                        if (error.errorCode !== "unknown") {
                            signins.value.push(error);
                            await autoFill(retries - 1);
                        }
                    }
                };
                autoFill(10);

                const loginSubmit = async (e) => {
                    const alias = e.target.alias.value;
                    if (isStepUp.value) {
                        const {token, error} = await p.stepup({
                            signinMethod: { alias: alias },
                            purpose: selectedPurpose.value
                        });

                        if (token) {
                            await signin(token);
                        } else {
                            if (error.errorCode !== "unknown") {
                                signins.value.push(error);
                            }
                        }
                    } else {
                        const {token, error} = await p.signinWithAlias(alias);
                        if (token) {
                            await signin(token);
                        } else {
                            if (error.errorCode !== "unknown") {
                                signins.value.push(error);
                            }
                        }
                    }
                }

                async function signin(verify_token) {
                    if (!verify_token) return;

                    const result = await verifyWithBackend(verify_token);
                    signins.value.push(result);
                    console.log(signins.value);
                }
                return {
                    loginSubmit,
                    signins,
                    setShowOptions,
                    showOptions,
                    selectedPurpose,
                    submitLabel,
                    isStepUp,
                    tabs,
                    setTab,
                    setTabSelect
                }
            }
    }).mount('#xapp');

        async function verifyWithBackend(token) {
            console.warn("TOKEN", token);
            const res = await fetch("", {
                method: "POST",
                body: new URLSearchParams({ token }),
                headers: {
                    RequestVerificationToken: "@requestToken"
                }
            });

            console.log("Result from post", res)

            if (res.ok) {
                return await res.json();
            }

            return res;
        }
    </script>
    <script type="module">
        const isSupported = Passwordless.isBrowserSupported();
        if (!isSupported) {
            const registerCredentialFields = document.getElementById("registerCredentialFields");
            registerCredentialFields.disabled = true;
            const alert = document.getElementById("webauthn-unsupported-alert");
            alert.classList.remove("hidden");
        }
    </script>
}
